import pygame
import sys
import math

# 初始化pygame
pygame.init()
pygame.font.init()

# 确保中文能正常显示
font = pygame.font.SysFont(['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC'], 36)
small_font = pygame.font.SysFont(['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC'], 24)

# 游戏窗口设置
WIDTH, HEIGHT = 700, 750
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("五子棋")

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BOARD_COLOR = (205, 133, 63)  # 棋盘颜色（棕色）
GRID_COLOR = (0, 0, 0)  # 网格颜色
BLACK_STONE = (0, 0, 0)  # 黑棋
WHITE_STONE = (255, 255, 255)  # 白棋
HIGHLIGHT_COLOR = (255, 215, 0)  # 高亮颜色（金色）

# 棋盘设置
BOARD_SIZE = 15  # 15x15的棋盘
GRID_SIZE = 40  # 网格大小
BOARD_MARGIN = (WIDTH - (BOARD_SIZE - 1) * GRID_SIZE) // 2  # 棋盘边距

# 游戏状态
EMPTY = 0
BLACK_PLAYER = 1
WHITE_PLAYER = 2
game_board = [[EMPTY for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
current_player = BLACK_PLAYER
game_over = False
winner = EMPTY
winning_positions = []  # 连成五子的位置


# 绘制棋盘
def draw_board():
    # 绘制背景
    screen.fill(BOARD_COLOR)

    # 绘制网格线
    for i in range(BOARD_SIZE):
        # 横线
        pygame.draw.line(screen, GRID_COLOR,
                         (BOARD_MARGIN, BOARD_MARGIN + i * GRID_SIZE),
                         (BOARD_MARGIN + (BOARD_SIZE - 1) * GRID_SIZE, BOARD_MARGIN + i * GRID_SIZE),
                         2 if i == 0 or i == BOARD_SIZE - 1 else 1)
        # 竖线
        pygame.draw.line(screen, GRID_COLOR,
                         (BOARD_MARGIN + i * GRID_SIZE, BOARD_MARGIN),
                         (BOARD_MARGIN + i * GRID_SIZE, BOARD_MARGIN + (BOARD_SIZE - 1) * GRID_SIZE),
                         2 if i == 0 or i == BOARD_SIZE - 1 else 1)

    # 绘制星位（天元和四星）
    star_points = [(7, 7), (3, 3), (3, 11), (11, 3), (11, 11)]
    for x, y in star_points:
        pygame.draw.circle(screen, GRID_COLOR,
                           (BOARD_MARGIN + x * GRID_SIZE, BOARD_MARGIN + y * GRID_SIZE),
                           5)


# 绘制棋子
def draw_stones():
    for i in range(BOARD_SIZE):
        for j in range(BOARD_SIZE):
            if game_board[i][j] == BLACK_PLAYER:
                pygame.draw.circle(screen, BLACK_STONE,
                                   (BOARD_MARGIN + j * GRID_SIZE, BOARD_MARGIN + i * GRID_SIZE),
                                   GRID_SIZE // 2 - 2)
            elif game_board[i][j] == WHITE_PLAYER:
                pygame.draw.circle(screen, WHITE_STONE,
                                   (BOARD_MARGIN + j * GRID_SIZE, BOARD_MARGIN + i * GRID_SIZE),
                                   GRID_SIZE // 2 - 2)
                # 为白棋添加边框，使其更清晰
                pygame.draw.circle(screen, BLACK,
                                   (BOARD_MARGIN + j * GRID_SIZE, BOARD_MARGIN + i * GRID_SIZE),
                                   GRID_SIZE // 2 - 2, 1)

    # 高亮显示连成五子的棋子
    for i, j in winning_positions:
        pygame.draw.circle(screen, HIGHLIGHT_COLOR,
                           (BOARD_MARGIN + j * GRID_SIZE, BOARD_MARGIN + i * GRID_SIZE),
                           GRID_SIZE // 2 - 2, 3)


# 检查是否有玩家获胜
def check_winner(x, y, player):
    directions = [(0, 1), (1, 0), (1, 1), (1, -1)]  # 水平、垂直、对角线、反对角线
    for dx, dy in directions:
        count = 1  # 当前位置已经有一个棋子
        positions = [(x, y)]

        # 向一个方向查找
        i, j = x + dx, y + dy
        while 0 <= i < BOARD_SIZE and 0 <= j < BOARD_SIZE and game_board[i][j] == player:
            count += 1
            positions.append((i, j))
            i += dx
            j += dy

        # 向相反方向查找
        i, j = x - dx, y - dy
        while 0 <= i < BOARD_SIZE and 0 <= j < BOARD_SIZE and game_board[i][j] == player:
            count += 1
            positions.append((i, j))
            i -= dx
            j -= dy

        # 如果连成五子
        if count >= 5:
            return True, positions

    return False, []


# 将屏幕坐标转换为棋盘坐标
def screen_to_board(x, y):
    board_x = round((x - BOARD_MARGIN) / GRID_SIZE)
    board_y = round((y - BOARD_MARGIN) / GRID_SIZE)
    if 0 <= board_x < BOARD_SIZE and 0 <= board_y < BOARD_SIZE:
        return board_x, board_y
    return None, None


# 重置游戏
def reset_game():
    global game_board, current_player, game_over, winner, winning_positions
    game_board = [[EMPTY for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
    current_player = BLACK_PLAYER
    game_over = False
    winner = EMPTY
    winning_positions = []


# 主循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:  # 左键点击
            if not game_over:
                x, y = event.pos
                board_x, board_y = screen_to_board(x, y)

                if board_x is not None and board_y is not None and game_board[board_y][board_x] == EMPTY:
                    # 落子
                    game_board[board_y][board_x] = current_player

                    # 检查是否获胜
                    has_winner, positions = check_winner(board_y, board_x, current_player)
                    if has_winner:
                        game_over = True
                        winner = current_player
                        winning_positions = positions
                    else:
                        # 切换玩家
                        current_player = WHITE_PLAYER if current_player == BLACK_PLAYER else BLACK_PLAYER
            else:
                # 游戏结束后点击重置游戏
                reset_game()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r:  # 按R键重置游戏
                reset_game()

    # 绘制游戏
    draw_board()
    draw_stones()

    # 显示当前玩家
    player_text = f"当前玩家: {'黑棋' if current_player == BLACK_PLAYER else '白棋'}"
    text_surface = small_font.render(player_text, True, BLACK)
    screen.blit(text_surface, (WIDTH // 2 - text_surface.get_width() // 2, HEIGHT - 40))

    # 显示游戏结束信息
    if game_over:
        winner_text = f"游戏结束! {'黑棋' if winner == BLACK_PLAYER else '白棋'}获胜!"
        text_surface = font.render(winner_text, True, BLACK)
        screen.blit(text_surface, (WIDTH // 2 - text_surface.get_width() // 2, HEIGHT - 80))

        restart_text = "点击任意位置或按R键重新开始"
        text_surface = small_font.render(restart_text, True, BLACK)
        screen.blit(text_surface, (WIDTH // 2 - text_surface.get_width() // 2, HEIGHT - 40))

    # 更新显示
    pygame.display.flip()

pygame.quit()
sys.exit()